home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Freeware / Read It Later 0.9924 / read_it_later-0.9924-fx.xpi / chrome / isreaditlater.jar / content / ISRILoffline.js < prev    next >
Text File  |  2008-10-28  |  13KB  |  375 lines

  1. function ISRILoffline()
  2. {
  3.     this.numOfThreads = 2;
  4.     this.viewing = null;
  5.     this.queue = new Object();
  6.     this.queueItemLoaded = new Object();
  7.     this.queueSize = 0;
  8.     this.threadsOpen = new Array();
  9.     this.threadTO = 14 * 1000;
  10.     this.threadTOs = new Object();
  11. }
  12.  
  13. ISRILoffline.prototype = {
  14.     
  15.     _init : function() {
  16.         //File delim
  17.         this.FD = ((navigator.platform=='Win32')?('\\'):('//'));
  18.         
  19.         Components.utils.import("resource://rilglobals/ISRILglobals.js");
  20.         
  21.         //File Service
  22.         this.sFile = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
  23.         this.file = this.sFile.get("ProfD", Components.interfaces.nsIFile);
  24.         
  25.         //Download Prefs
  26.         this.bPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("browser.");
  27.  
  28.         
  29.         //Directory Locations
  30.         this.prefix = 'RIL ';
  31.         this.offlineFolderName = 'Read-It-Later Offline';
  32.         this.offlinePath = this.file.path + this.FD + this.offlineFolderName;
  33.         
  34.         //Create Offline Folder If it Doesn't Exist
  35.         this.file.append( this.offlineFolderName );
  36.         if( !this.file.exists() || !this.file.isDirectory() ) {   // if it doesn't exist, create
  37.            this.file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
  38.            ISRILprefs.setPref("offline_dir", this.offlinePath);    
  39.         }
  40.         
  41.         /*if (ISRILxul.bip('iframes') && ISRILxul.bip('iframes').tagName == 'panel') {
  42.             ISRILxul.bip('iframes').setAttribute('hidden', false);
  43.             ISRILxul.bip('iframes').openPopup( ISRILxul.bip('content') , "after_end", -5000, -5000);        
  44.         }*/
  45.         
  46.         if (ISRILglobals.flagRenameFiles) { this.renameFiles(); }
  47.         
  48.     },
  49.     
  50.     GoOffline : function(single) {        
  51.         
  52.         if (navigator.onLine) {            
  53.             
  54.             //This part here seems wasteful, but we can't modify the result list directly (cannot modify properties of a wrappednative)
  55.             ISRILoffline.queueSize = 0;
  56.             var resultList = ISRIL.GetList(11);
  57.             for(i in resultList) {
  58.                 ISRILoffline.queue[ ISRILoffline.queueSize ] = {itemId:resultList[i].itemId, uri:resultList[i].uri};
  59.                 ISRILoffline.queueSize++;                    
  60.             }
  61.             ISRILoffline.OfflineStep(2);
  62.             
  63.             ISRILoffline.startQueue();
  64.             
  65.         } else {
  66.             ISRILxul.sPrompt.alert(window, ISRIL.l('OfflineTitle'), ISRIL.l('OfflineOffline'));    
  67.         }
  68.         
  69.     },
  70.     
  71.     addToQueue : function(id,resolve) {
  72.         
  73.         ISRILoffline.queue[ ISRILoffline.queueSize ] = {itemId:id, uri:ISRIL.sBookmarks.getBookmarkURI( id ).spec, resolve:resolve?resolve:false};
  74.         ISRILoffline.queueSize++;
  75.         ISRILoffline.startQueue();
  76.         
  77.     },
  78.     
  79.     startQueue : function() {
  80.         if (navigator.onLine) {
  81.             if (!ISRILoffline.queueRun) {        
  82.                 //Restart Queue
  83.                 ISRILoffline.queueRun             = true;
  84.                 ISRILoffline.k                 = true;
  85.                 ISRILoffline.processed             = 0;
  86.                 ISRILoffline.skipped             = 0;
  87.                 ISRILoffline.timedOut             = 0;
  88.                 
  89.                 ISRILoffline.createIframes();
  90.                 
  91.                 //when downloading images, make sure it doesn't try to autofit it into the 1x1 hidden iframe
  92.                 //we store their current setting so we can set it back after the downloads are complete
  93.                 ISRILoffline.oldbPref = ISRILoffline.bPrefs.getBoolPref('enable_automatic_image_resizing');
  94.                 ISRILoffline.bPrefs.setBoolPref('enable_automatic_image_resizing', false);
  95.                 ISRILoffline.tmp = ISRILoffline.bPrefs.getBoolPref('enable_automatic_image_resizing');
  96.  
  97.                 
  98.                 //Start - feed first batch into threads
  99.                 for(t=1; t<=ISRILoffline.numOfThreads; t++) {
  100.                     ISRILoffline.next();
  101.                 }
  102.             } else {
  103.                 ISRILoffline.next();    
  104.             }            
  105.         }
  106.         
  107.     },
  108.     
  109.     CheckQueue : function(noTO) {
  110.         //This could be improved, only having to check from processed items onwards.  Since it
  111.         //repeats checking pages that obviously have been processed already
  112.         var unprocessed = false;
  113.         ISRILoffline.counts = {'unprocessed':0,'processing':0,'downloaded':0,'timedOut':0,'skipped':0};
  114.         
  115.         ISRIL.d('----');
  116.         for (var qp in ISRILoffline.queue) {
  117.             if (!unprocessed && !ISRILoffline.queue[qp].status) {
  118.                 unprocessed = qp;
  119.             }
  120.             status = ISRILoffline.queue[qp].status ? ISRILoffline.queue[qp].status : 'unprocessed';
  121.             ISRILoffline.counts[ status ]++;
  122.             ISRIL.d(qp + ' - ' + status + ' - ' + ISRILoffline.queue[qp].thread );
  123.         }
  124.         
  125.         if (ISRILxul.bip('OfflineMeter')) {
  126.             //Show Progress        
  127.             totalDone = ISRILoffline.counts['downloaded'] + ISRILoffline.counts['skipped'] + ISRILoffline.counts['timedOut'];
  128.             totalProcessing = totalDone + ISRILoffline.counts['processing'];
  129.                     
  130.             ISRILxul.bip('OfflineMeter').value = Math.round( totalProcessing / ISRILoffline.queueSize * 100 );
  131.             ISRILxul.bip('OfflineMeterDone').value = Math.round( totalDone / ISRILoffline.queueSize * 100 );
  132.             ISRILxul.bip('OfflineMeterText').value = totalDone + ' / ' + ISRILoffline.queueSize;
  133.         }
  134.         if (!unprocessed && !noTO) { //nothing left to do, wait for timeouts and then force finish
  135.             ISRIL.d('final timeout');
  136.             
  137.             //If there is nothing left to process, then only wait 1 second (give time for other items in batch to show up)
  138.             waitTime = (ISRILoffline.counts[ 'processing' ] > 0) ? ISRILoffline.threadTO : 1000; 
  139.             ISRILoffline.finalQueueTO = setTimeout('ISRILoffline.OfflineBatchDone();', waitTime);
  140.             
  141.         }
  142.         
  143.         return unprocessed;
  144.     },
  145.     
  146.     next : function() {
  147.         
  148.         /*
  149.          Check Queue - If next() was called, something changed, so update the queue meter with check queue and get an unprocessed item if one exists
  150.          Go through queue and find the first unprocessed item
  151.             Get a thread
  152.                 Start Processing
  153.             No Thread?
  154.                 Do nothing - wait till a thread is free
  155.         */
  156.         
  157.         var qp = ISRILoffline.CheckQueue();
  158.         if (qp) {
  159.             if (ISRILoffline.k) {
  160.                 var freeThread = ISRILoffline.getFreeThread(); // Get a Thread
  161.                 if (freeThread)  { //Has an open Thread
  162.                         
  163.                     Item = ISRILoffline.queue[qp];
  164.                     if (!ISRILoffline.getF(Item.itemId).exists()) {                
  165.                         iframe = ISRILxul.bi(ISRILoffline.getIframeId(freeThread));                
  166.                         iframe.setAttribute('i', Item.itemId);            
  167.                         iframe.setAttribute('qp', qp);
  168.                         iframe.webNavigation.loadURI(Item.uri,Components.interfaces.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE,null,null,null);    
  169.                         ISRILoffline.queue[qp].status = 'processing';
  170.                         ISRILoffline.queue[qp].thread = freeThread;
  171.                         ISRILoffline.threadTOs[freeThread] = setTimeout('ISRILoffline.threadTimedOut('+freeThread+','+qp+')', ISRILoffline.threadTO);
  172.                     } else {
  173.                         ISRILoffline.queue[qp].status = 'skipped';    
  174.                         ISRILoffline.unlockThread(freeThread);
  175.                         ISRILoffline.next();
  176.                     }
  177.                     
  178.                 } //do nothing - wait until a thread is freed
  179.             }
  180.         }
  181.  
  182.     },
  183.     
  184.     getFreeThread : function() {
  185.         for(var i=1; i<=ISRILoffline.threadsOpen.length; i++) {
  186.             if (ISRILoffline.threadsOpen[i]) {
  187.                 ISRILoffline.threadsOpen[i] = false;                
  188.                 return i;    
  189.             }
  190.         }
  191.         return false;
  192.     },
  193.     
  194.     unlockThread : function(t) {
  195.         clearInterval( ISRILoffline.threadTOs[t] );
  196.         ISRILoffline.threadsOpen[t] = true;
  197.     },
  198.     
  199.     threadTimedOut : function(t, qp) {
  200.         ISRILoffline.unlockThread(t);
  201.         ISRILoffline.queue[qp].status = 'timedOut';
  202.         ISRILoffline.next();
  203.     },
  204.         
  205.     createIframes : function() {        
  206.         
  207.         if ( !ISRILxul.bi( ISRILoffline.getIframeId(ISRILoffline.numOfThreads-1) ) ) {            
  208.             for(i=1; i<=ISRILoffline.numOfThreads; i++) {
  209.                 //http://developer.mozilla.org/en/docs/Code_snippets:HTML_to_DOM
  210.                 id = ISRILoffline.getIframeId(i);
  211.                 iframe = ISRILxul.createNode('iframe', {type:"content", thread:i, name:id, id:id, hidden:"false", width:"1000", height:"1000"});
  212.                 ISRILxul.bip('iframes').appendChild(iframe);
  213.                 iframe.webNavigation.allowAuth = true;
  214.                 iframe.webNavigation.allowImages = true;
  215.                 iframe.webNavigation.allowJavascript = false;
  216.                 iframe.webNavigation.allowMetaRedirects = true;
  217.                 iframe.webNavigation.allowPlugins = false;
  218.                 iframe.webNavigation.allowSubframes = false;
  219.     
  220.                 iframe.addEventListener("load", ISRILoffline.iframe_onPageLoad, true);    
  221.                 
  222.                 ISRILoffline.threadsOpen[ i ] = true;
  223.             }
  224.         }
  225.         return true;
  226.     },
  227.     
  228.     iframe_onPageLoad: function(aEvent) {
  229.         
  230.         var doc = aEvent.originalTarget;
  231.         var url = doc.location.href;
  232.         var id = this.getAttribute('i');
  233.         var qp = this.getAttribute('qp');
  234.         var t = this.getAttribute('thread');
  235.  
  236.         if (ISRILoffline.queue[qp] && !ISRILoffline.queueItemLoaded[qp] && id) { 
  237.             if (aEvent.originalTarget.nodeName == "#document") { // ok, it's a real page, let's do our magic
  238.                 ISRILoffline.saveDoc(doc, id);
  239.                 ISRILoffline.queue[qp].status = 'downloaded';
  240.                 
  241.                 ISRILoffline.queueItemLoaded[qp] = true;
  242.                 
  243.                 ISRILoffline.unlockThread(t);
  244.                 
  245.                 ISRILoffline.next();
  246.             }
  247.         }
  248.     },
  249.     
  250.     saveDoc : function(aDocument, i) {
  251.                         
  252.         var wbp = Components.classes['@mozilla.org/embedding/browser/nsWebBrowserPersist;1']  
  253.                   .createInstance(Components.interfaces.nsIWebBrowserPersist);  
  254.         wbp.saveDocument(aDocument, ISRILoffline.getF( i ), ISRILoffline.openF( ISRILoffline.iURL(i, '_files', true) ), null, null, null);              
  255.  
  256.     },
  257.     
  258.     OfflineStep : function(s) {
  259.         ISRILoffline.step = s;
  260.         if (ISRILxul.bip('OfflineMeter')) {
  261.             ISRILxul.bip('OfflineStep1').setAttribute('hidden', ( (s==1) ? (false) : (true) ) );
  262.             ISRILxul.bip('OfflineStep2').setAttribute('hidden', ( (s==2) ? (false) : (true) ) );
  263.             ISRILxul.bip('OfflineStep3').setAttribute('hidden', ( (s==3) ? (false) : (true) ) );
  264.             return true;
  265.         }
  266.     },
  267.     
  268.     OfflineBatchDone : function() {
  269.         if (!ISRILoffline.CheckQueue(true) && ISRILoffline.queueRun) {
  270.             ISRIL.d('OFFLINE BATCH DONE');
  271.             ISRILoffline.queueRun = false;
  272.             
  273.             if ( ISRILoffline.OfflineStep(3) ) {
  274.                 var contentStr = ISRIL.l('Alright1') + ' ' + ISRILoffline.counts['downloaded'] + ' ';
  275.                 contentStr += ISRIL.l('Alright2') + ' ' + ISRILoffline.counts['skipped'] + ' ' + ISRIL.l('Alright3') + ' ';
  276.                 contentStr += (ISRILoffline.counts['timedOut'] + ISRILoffline.counts['processing']) + ' ' + ISRIL.l('Alright4');
  277.                 ISRILxul.bip('Alright').textContent = contentStr;
  278.             }
  279.             
  280.             ISRILoffline.queue = new Object();
  281.             ISRILoffline.queueItemLoaded = new Object();
  282.             ISRILoffline.queueSize = 0;    
  283.             ISRILoffline.processed = 0;    
  284.             ISRILoffline.skipped = 0;
  285.             ISRILoffline.timedOut = 0;
  286.             
  287.             ISRILoffline.CloseOut();
  288.             
  289.             for(i=1; i<=ISRILoffline.numOfThreads; i++) {
  290.                 //id = ISRILoffline.getIframeId(i);
  291.                 //ISRILxul.bi(id).parentNode.removeChild(ISRILxul.bi(id));
  292.                 ISRILoffline.unlockThread(i);
  293.             }
  294.         }
  295.     },
  296.     
  297.     CloseOut : function() { 
  298.         //Why is this on settimeout?
  299.         setTimeout("ISRILoffline.bPrefs.setBoolPref('enable_automatic_image_resizing', ISRILoffline.oldbPref);", 1000);        
  300.     },
  301.     
  302.     Cancel : function() {
  303.         ISRILoffline.k = false;
  304.         ISRILoffline.CloseOut();
  305.         return true;
  306.     },    
  307.     
  308.     getIframeId : function(i) {
  309.         return "isRitL-iframe-"+i;
  310.     },
  311.     
  312.     getF : function( id , ext) { return ISRILoffline.openF( ISRILoffline.iURL( id , ext ) ); },
  313.     
  314.     iURL : function(id, suffix, noDot) {
  315.         if (!suffix) { suffix = 'html'; }
  316.         return (ISRILoffline.offlinePath + ISRILoffline.FD + ISRILoffline.prefix + id + (noDot?'':'.') + suffix);        
  317.     },
  318.     
  319.     openF : function(uri) {
  320.         var file = Components.classes["@mozilla.org/file/local;1"]
  321.                      .createInstance(Components.interfaces.nsILocalFile); 
  322.         file.initWithPath(uri);
  323.         return file;
  324.     },
  325.     
  326.     Serve : function(id) {
  327.         var offlineURL = 'file:///' + ISRILoffline.u(id);
  328.         
  329.         if (ISRILoffline.getF(id).exists()) {
  330.             setTimeout("ISRIL.GoTo('" + offlineURL + "', '" + id + "');", 10);
  331.         } else {
  332.             setTimeout("ISRILxul.NotSavedOffline()", 10);
  333.         }
  334.     },
  335.     
  336.     u : function(id, ext) {
  337.         return encodeURI( ISRILoffline.iURL( id , ext ).replace(/\\/g,'/') );
  338.     },
  339.     
  340.     deleteOffline : function(id) {
  341.         file = ISRILoffline.getF( id );
  342.         if (file.exists()) {
  343.             file.remove(false);
  344.             
  345.             file = ISRILoffline.openF( ISRILoffline.iURL(id, '_files', true) );
  346.             if (file.exists()) { file.remove(true); }
  347.         }
  348.     },
  349.     
  350.     // -- Versioning -- //
  351.     
  352.     //Version 0.99 changes the filenames of offline items, this will go through any items saved and rename them.
  353.     renameFiles : function() {
  354.         try {
  355.             var dir = ISRILoffline.openF( ISRILoffline.offlinePath + ISRILoffline.FD );
  356.             
  357.             var list = ISRIL.GetList();
  358.             for(var i in list) {
  359.                 id = list[i].itemId;
  360.                 file = ISRILoffline.openF( ISRILoffline.offlinePath + ISRILoffline.FD + ISRILoffline.prefix + ISRIL.sBookmarks.getItemGUID(id) + '.html' );
  361.                 if (file.exists()) {
  362.                     file.moveTo(dir,  ISRILoffline.prefix + id + '.html' );
  363.                     
  364.                     //asset directory
  365.                     file = ISRILoffline.openF( ISRILoffline.offlinePath + ISRILoffline.FD + ISRILoffline.prefix + ISRIL.sBookmarks.getItemGUID(id) + '_files' );
  366.                     if (file.exists()) {
  367.                         file.remove(true);
  368.                     }
  369.                 }
  370.             }
  371.         } catch(e) { }
  372.     },
  373. }
  374.  
  375. var ISRILoffline = new ISRILoffline();